home *** CD-ROM | disk | FTP | other *** search
- #include "SpriteTools.h"
-
- /*
-
- SpriteEngine
- ============
-
- This demo sprite engine is designed for the following structure:
- (Lower units use the higher ones.)
-
- SpriteTools.c: Utilities for loading and drawing
- |
- SpriteHanders.c: All custom code: Sprite init, movement, collisions
- |
- SpriteEngine.c: Main program, sprite engine
-
- The only files you need to edit in order to change the sprite behavior are
- the files SpriteHandlers.c and SpriteHandlers.h.
-
- */
-
-
- /* The actual sprite engine */
-
-
- static void InitSpriteEngine(Rect *offBounds, short backgroundPictureID)
- {
- PicHandle backgroundPicture;
- GDHandle saveGD;
- GWorldPtr savePort;
-
- MyNewGWorld(&gOffScreen, offBounds);
- MyNewGWorld(&gBackScreen, offBounds);
-
- GetGWorld(&savePort, &saveGD); /*Save the port/device*/
- SetGWorld((GWorldPtr)gBackScreen, nil);
-
- EraseRect(offBounds);
-
- backgroundPicture = GetPicture(backgroundPictureID);
- if (backgroundPicture != nil)
- {
- DrawPicture(backgroundPicture, offBounds);
- ReleaseResource((Handle)backgroundPicture);
- }
- SetGWorld((GWorldPtr)gOffScreen, nil);
- CopyBits(&gBackScreen->portBits, &gOffScreen->portBits, offBounds, offBounds, srcCopy, nil);
- SetGWorld((GWorldPtr)myWindow, GetMainDevice());
- CopyBits(&gOffScreen->portBits, &myWindow->portBits, offBounds, offBounds, srcCopy, nil);
- SetGWorld(savePort, saveGD);
- } /*InitSpriteEngine*/
-
-
-
- static void RunSpriteEngine()
- {
- #define kWallBounce 7 /*1/10-ths of speed kept after wallbounce*/
- #define kBallDiameterSquared (32*32) /*Diameter 32, squared*/
-
- Rect tmpRect;
- GDHandle saveGD;
- GWorldPtr savePort;
- SpritePtr theSprite, anotherSprite;
- Rect bounds1, bounds2;
-
- GetGWorld(&savePort, &saveGD); /*Save the port/device*/
- /*1: Erase all sprites from gOffScreen*/
- /*Note: We keep the rectangles for erasing on the screen, later.*/
- SetGWorld((GWorldPtr)gOffScreen, nil);
-
- theSprite = gSpriteList;
- while (theSprite != nil)
- {
- theSprite->drawingRect = theSprite->face->portRect;
- OffsetRect(&theSprite->drawingRect, theSprite->position.h, theSprite->position.v);
- CopyBits(&gBackScreen->portBits, &gOffScreen->portBits, &theSprite->drawingRect, &theSprite->drawingRect, srcCopy, nil);
-
- theSprite = theSprite->next;
- }
-
- /*2: Change the position and speed*/
- theSprite = gSpriteList;
- while (theSprite != nil)
- {
- MoveSprite(theSprite);
-
- theSprite = theSprite->next;
- }/*position/speed loop*/
-
- /*3: Check for collisions*/
- theSprite = gSpriteList;
- while (theSprite != nil) /*For all sprites in the list…*/
- {
- bounds1 = theSprite->face->portRect;
- OffsetRect(&bounds1, theSprite->position.h, theSprite->position.v);
-
- anotherSprite = theSprite->next;
- while (anotherSprite != nil)
- {
- /*compare its position to all following sprites*/
- bounds2 = anotherSprite->face->portRect;
- OffsetRect(&bounds2, anotherSprite->position.h, anotherSprite->position.v);
-
- if (SectRect(&bounds1, &bounds2, &tmpRect))
- HitSprite(theSprite, anotherSprite);
-
- anotherSprite = anotherSprite->next;
- }
- theSprite = theSprite->next;
- } /*collision loop*/
-
- /*4: Draw sprites in gOffScreen*/
- /*Note: PlotCIcon or DrawPicture are not very fast! We can speed it up my*/
- /*pre-drawing them in some offscreen, and CopyBits them from there.*/
- theSprite = gSpriteList;
- while (theSprite != nil) /*For all sprites in the list…*/
- {
- tmpRect = theSprite->face->portRect;
- OffsetRect(&tmpRect, theSprite->position.h, theSprite->position.v);
- PlotFace(theSprite->face, gOffScreen, *(Point *)&tmpRect);
-
- theSprite = theSprite->next;
- }
-
- /*5: Copy sprites to the screen (gWind) - both old and new position!*/
- /*Note: Depending on what limitations we have on movement, we may be able to avoid the multiple*/
- /*CopyBitsing here. E.g. if sprites always move a maximum of 2 pixels, we can copy a 2 pixels*/
- /*larger area, etc.*/
- SetGWorld((GWorldPtr)myWindow, saveGD); /*Vilken GD???*/
- theSprite = gSpriteList;
- while (theSprite != nil) /*For all sprites in the list…*/
- {
- CopyBits(&gOffScreen->portBits, &myWindow->portBits, &theSprite->drawingRect, &theSprite->drawingRect, srcCopy, nil);
- theSprite->drawingRect = theSprite->face->portRect;
- OffsetRect(&theSprite->drawingRect, theSprite->position.h, theSprite->position.v);
- CopyBits(&gOffScreen->portBits, &myWindow->portBits, &theSprite->drawingRect, &theSprite->drawingRect, srcCopy, nil);
-
- theSprite = theSprite->next;
- }
- SetGWorld(savePort, saveGD);
- }; /*RunSpriteEngine*/
-
-
-
- /* Standard inits */
-
- static void InitToolbox(void) {
- InitGraf (&qd.thePort);
- InitFonts ();
- FlushEvents (everyEvent,0);
- InitWindows ();
- InitMenus ();
- TEInit ();
- InitDialogs (nil);
- InitCursor ();
- } /*InitToolbox*/
-
-
- /* Initialize - create window, load graphics */
-
- static void InitStuff()
- {
- Rect windowRectangle;
-
- /*Set up the window*/
- SetRect(&windowRectangle, 50, 50, 450, 350);
- myWindow = NewCWindow(nil, &windowRectangle, "\pSprite test", true, documentProc, (WindowPtr)-1L, false, 0);
- SetPort(myWindow);
-
- qd.randSeed = TickCount (); /*Seed the random number generator*/
- } /*InitStuff*/
-
-
- #define kBackgroundPictureID 128
-
-
- /* Main program */
-
- void main(void)
- {
- long startTime;
-
- InitToolbox();
- InitStuff();
- InitSpriteEngine(&myWindow->portRect, kBackgroundPictureID);
- InitSprites();
-
- HideCursor();
- while (!Button())
- {
- startTime = TickCount();
- RunSpriteEngine();
- while (TickCount() < startTime + kFrameTime);
- }
- ShowCursor();
-
- FlushEvents(mDownMask, 0);
- } /*main*/
-
-